home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / p4 / p4-1_2a.lha / p4-1.2a / lib / p4_error.c < prev    next >
C/C++ Source or Header  |  1992-10-19  |  4KB  |  158 lines

  1. #include "p4.h"
  2. #include "p4_sys.h"
  3.  
  4. extern P4VOID exit();
  5.  
  6. static int interrupt_caught = 0; /* True if an interrupt was caught */
  7.  
  8. #if defined(ENCORE) || defined(SYMMETRY) || defined(TITAN) || \
  9.     defined(SGI)    || defined(GP_1000)  || defined(TC_2000)
  10. #define P4_HANDLER_TYPE int
  11. #else
  12. #define P4_HANDLER_TYPE P4VOID
  13. #endif
  14.  
  15. static P4_HANDLER_TYPE (*prev_sigint_handler) () = NULL;
  16. static P4_HANDLER_TYPE (*prev_sigsegv_handler) () = NULL;
  17. static P4_HANDLER_TYPE (*prev_sigbus_handler) () = NULL;
  18. static P4_HANDLER_TYPE (*prev_sigfpe_handler) () = NULL;
  19. static P4_HANDLER_TYPE (*prev_err_handler) () = NULL;
  20. static int err_sig, err_code;
  21. static struct sigcontext *err_scp;
  22. static char *err_addr;
  23.  
  24.  
  25. int p4_soft_errors(onoff)
  26. int onoff;
  27. {
  28.     int old;
  29.  
  30.     if (!p4_local)
  31.     p4_error("p4_soft_errors: p4_local must be allocated first", 0);
  32.  
  33.     old = p4_local->soft_errors;
  34.     p4_local->soft_errors = onoff;
  35.     return old;
  36. }
  37.  
  38. P4VOID p4_error(string, value)
  39. char *string;
  40. int value;
  41. {
  42.     SIGNAL_P4(SIGINT,SIG_IGN);
  43.     fflush(stdout);
  44.     printf("%s:  p4_error: %s: %d\n",whoami,string,value);
  45.     if (value < 0)
  46.         perror("    p4_error: latest msg from perror");
  47.     fflush(stdout);
  48.  
  49.     /* Send interrupt to all known processes */
  50.     zap_p4_processes();
  51.  
  52.     /* shutdown(sock,2), close(sock) all sockets */
  53. #   ifdef CAN_DO_SOCKET_MSGS
  54.     shutdown_p4_socks();
  55. #   endif
  56.  
  57. #   ifdef SYSV_IPC
  58.     remove_sysv_ipc();
  59. #   endif
  60.  
  61.     if (interrupt_caught && value != SIGINT)
  62.     {
  63.     switch (value)
  64.     {
  65.       case SIGSEGV:
  66.         prev_err_handler = prev_sigsegv_handler;
  67.         break;
  68.       case SIGBUS:
  69.         prev_err_handler = prev_sigbus_handler;
  70.         break;
  71.       case SIGFPE:
  72.         prev_err_handler = prev_sigfpe_handler;
  73.         break;
  74.       default:
  75.         printf("p4_error: unidentified err handler\n");
  76.         prev_err_handler = NULL;
  77.         break;
  78.     }
  79.     if (prev_err_handler == (P4_HANDLER_TYPE (*) ()) NULL)
  80.     {
  81.         /* return to default handling of the interrupt by the OS */
  82.         SIGNAL_P4(value,SIG_DFL); 
  83. #           if defined(NEXT)  ||  defined(KSR)
  84.             kill(getpid(),value);
  85. #           endif
  86.         return;
  87.     }
  88.     else
  89.     {
  90.         (*prev_err_handler) (err_sig, err_code, err_scp, err_addr);
  91.     }
  92.     }
  93.     else
  94.     {
  95.     exit(1);
  96.     }
  97. }
  98.  
  99. static P4_HANDLER_TYPE sig_err_handler(sig, code, scp, addr)
  100. int sig, code;
  101. struct sigcontext *scp;
  102. char *addr;
  103. {
  104.     interrupt_caught = 1;
  105.     err_sig = sig;
  106.     err_code = code;
  107.     err_scp = scp;
  108.     err_addr = addr;
  109.     if (sig == 11)
  110.     p4_error("interrupt SIGSEGV", sig);
  111.     else if (sig == 10)
  112.     p4_error("interrupt SIGBUS", sig);
  113.     else if (sig == 8)
  114.     p4_error("interrupt SIGFPE", sig);
  115.     else if (sig == 2)
  116.     p4_error("interrupt SIGINT", sig);
  117.     else
  118.     p4_error("interrupt SIGx", sig);
  119. }
  120.  
  121.  
  122. /*
  123.   Trap signals so that we can propagate error conditions and tidy up 
  124.   shared system resources in a manner not possible just by killing procs
  125. */
  126. P4VOID trap_sig_errs()
  127. {
  128.     P4_HANDLER_TYPE (*rc) ();
  129.  
  130.     rc = SIGNAL_P4(SIGINT, sig_err_handler);
  131.     if (rc == (P4_HANDLER_TYPE (*) ()) -1)
  132.     p4_error("trap_sig_errs: SIGNAL_P4 failed", SIGINT);
  133.     if (((int) rc > 1)  &&  (rc != sig_err_handler))
  134.     prev_sigint_handler = rc;
  135.  
  136. /* we can not handle sigsegv on symmetry and balance because they use 
  137.  * it for shmem stuff 
  138. */
  139. #ifdef CAN_HANDLE_SIGSEGV
  140.     rc = SIGNAL_P4(SIGSEGV, sig_err_handler);
  141.     if ((int) rc == -1)
  142.     p4_error("trap_sig_errs: SIGNAL_P4 failed", SIGSEGV);
  143.     if (((int) rc > 1)  &&  (rc != sig_err_handler))
  144.     prev_sigsegv_handler = rc;
  145. #endif
  146.  
  147.     rc = SIGNAL_P4(SIGBUS, sig_err_handler);
  148.     if ((int) rc == -1)
  149.     p4_error("trap_sig_errs: SIGNAL_P4 failed", SIGBUS);
  150.     if (((int) rc > 1)  &&  (rc != sig_err_handler))
  151.     prev_sigbus_handler = rc;
  152.     rc = SIGNAL_P4(SIGFPE, sig_err_handler);
  153.     if ((int) rc == -1)
  154.     p4_error("trap_sig_errs: SIGNAL_P4 failed", SIGFPE);
  155.     if (((int) rc > 1)  &&  (rc != sig_err_handler))
  156.     prev_sigfpe_handler = rc;
  157. }
  158.